package com.ctshk.common.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author 谢诗宏
 * @description 实体转化工具
 * @date 2020/12/24
 */
@Slf4j
public class EntityUtil {

    /**
     * @param object 要强转的对象 , entityClass 强转后的类型
     * @return T
     */
    public static <T> T convertBean(Object object, Class<T> entityClass) {
        if (null == object) {
            return null;
        }
        return JSON.parseObject(JSON.toJSONString(object), entityClass);
    }

    /**
     * @param object 要转话的对象
     * @return java.util.Map<?, ?>
     */
    public static Map<?, ?> objectToMap(Object object) {
        return convertBean(object, Map.class);
    }

    /**
     * @param source 资源对象, target 目标对象, ignoreProperties 赋值new String[]{}
     * @return T  target对象
     */
    public static <T> T copy(Object source, Class<T> target, String... ignoreProperties) {
        if (null == source) {
            return null;
        }
        T targetInstance = null;
        try {
            targetInstance = target.newInstance();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        if (ArrayUtils.isEmpty(ignoreProperties)) {
            assert targetInstance != null;
            BeanUtils.copyProperties(source, targetInstance);
        } else {
            assert targetInstance != null;
            BeanUtils.copyProperties(source, targetInstance, ignoreProperties);
        }
        return targetInstance;
    }


    /**
     * @param list, target, ignoreProperties]
     * @return java.util.List<T>
     */
    public static <T, E> List<T> copyList(List<E> list, Class<T> target, String... ignoreProperties) {
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        List<T> targetList = new ArrayList<T>(list.size());
        for (E e : list) {
            targetList.add(copy(e, target, ignoreProperties));
        }
        return targetList;
    }


    /**
     * 功能描述: Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
     *
     * @param obj Object
     * @return java.util.Map<java.lang.String, java.lang.String>
     */
    public static Map<String, String> transBean2Map(Object obj) {
        if (obj == null) {
            return null;
        }
        Map<String, String> map = new HashMap<String, String>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (Objects.equals("class", key)) {
                    continue;
                }
                // 得到property对应的getter方法
                Method getter = property.getReadMethod();
                Object value = getter.invoke(obj);
                map.put(key, value.toString());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return map;
    }


    /**
     * copyProperties 忽略null值字段
     *
     * @param source 源数据
     * @return String数组
     */
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * @param
     * @return 是/否
     * @description 校验对象里面所有字段是否为空
     * @author hef
     * @date 2021/04/07
     */
    public static boolean allFieldIsNull(Object o) {
        try {
            if (Objects.isNull(o)) return true;
            for (Field field : o.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                Object object = field.get(o);
                if (!Objects.isNull(object)) {
                    if (object instanceof String) {
                        if (StringUtils.isNotBlank((String) object))
                            return false;
                    } else if (object instanceof Collection) {
                        if (CollectionUtil.isNotEmpty((Collection) object))
                            return false;
                    } else if (object instanceof Map) {
                        if (MapUtil.isNotEmpty((Map) object))
                            return false;
                    } else {
                        return false;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

}
